package com.carbon.system.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * 请求日志拦截器，用于在HTTP请求过程中记录详细的请求和响应信息
 */
@Slf4j
public class LoggingRequestInterceptor implements ClientHttpRequestInterceptor {

    /**
     * 拦截HTTP请求和响应，以记录其详细信息
     *
     * @param request HTTP请求
     * @param body 请求体数据
     * @param execution 请求执行器
     * @return 服务器对请求的响应
     * @throws IOException 如果在读取响应时发生I/O错误
     */
    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        // 记录请求信息
        traceRequest(request, body);
        // 继续执行请求并获取响应
        ClientHttpResponse response = execution.execute(request, body);
        // 记录响应信息
        traceResponse(response);
        return response;
    }

    /**
     * 记录HTTP请求的详细信息，包括URI、方法、头信息和请求体
     *
     * @param request HTTP请求
     * @param body 请求体数据
     * @throws IOException 如果在读取请求体时发生I/O错误
     */
    private void traceRequest(HttpRequest request, byte[] body) throws IOException {
        log.info("===========================request begin================================================");
        log.info("URI         : {}", request.getURI());
        log.info("Method      : {}", request.getMethod());
        log.info("Headers     : {}", request.getHeaders() );
        log.info("Request body: {}", new String(body, "UTF-8"));
        log.info("==========================request end================================================");
    }

    /**
     * 记录HTTP响应的详细信息，包括状态码、状态文本、头信息和响应体
     *
     * @param response 服务器对请求的响应
     * @throws IOException 如果在读取响应体时发生I/O错误
     */
    private void traceResponse(ClientHttpResponse response) throws IOException {
        StringBuilder inputStringBuilder = new StringBuilder();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(response.getBody(), "UTF-8"));
        String line = bufferedReader.readLine();
        while (line != null) {
            inputStringBuilder.append(line);
            inputStringBuilder.append('\n');
            line = bufferedReader.readLine();
        }
        log.info("============================response begin==========================================");
        log.info("Status code  : {}", response.getStatusCode());
        log.info("Status text  : {}", response.getStatusText());
        log.info("Headers      : {}", response.getHeaders());
        log.info("Response body: {}", inputStringBuilder.toString());
        log.info("=======================response end=================================================");
    }

}
